﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
using System.Collections.Generic;
using System.Windows.Forms;

namespace MidasPoster
{
    public class DBManager
    {
        private static volatile DBManager m_Instance = null;
        private string m_ConnectUrl = "mongodb://localhost:27017";
        private string m_databaseName = "midasposter";
        private MongoServer gmongoServer = null;
        private MongoDatabase mongoDatabase = null;
        private bool m_bAdmin = false;
        private bool m_bSuccessLogin = false;
        private string m_strLoginUserName = "";
        private Dictionary<EDBINFOS, MongoCollection<BsonDocument>> _keyindexCollection = new Dictionary<EDBINFOS, MongoCollection<BsonDocument>>();
        private AutoIndexManager _autoIndexMgr = null;
        private DBManager()
        {
        }
        public bool IsAdmin {get{return m_bAdmin;}}
        public bool IsSuccessLogin { get { return m_bSuccessLogin; } }
        public string LoginUserName { get { return m_strLoginUserName; } }
        public AutoIndexManager getAutoIndexManager { get { return _autoIndexMgr; } }

        public static DBManager Singleton
        {
            get 
            { 
                if (m_Instance == null) 
                {
                    lock (typeof(DBManager))
                    { 
                        if (m_Instance == null)
                        {
                            m_Instance = new DBManager(); 
                        } 
                    } 
                }
                return m_Instance;
            } 
        }
        public void OpenServerUrl(string strUrl,string strPort,string username,string password)
        {
            m_ConnectUrl = "mongodb://" + strUrl + ":" + strPort;
            
            
            //MongoClient mongo = new MongoClient(m_ConnectUrl);

            var credential = MongoCredential.CreateMongoCRCredential(m_databaseName, username, password);
            //Server settings
            var settings = new MongoClientSettings
            {
                Credentials = new[] { credential },
                Server = new MongoServerAddress(strUrl, Convert.ToInt32(strPort))
            };

            //Get a Reference to the Client Object
            MongoClient mongo = new MongoClient(settings);
            
            gmongoServer = mongo.GetServer();
            
            try
            {
                mongoDatabase = gmongoServer.GetDatabase(m_databaseName) as MongoDatabase;

                MongoCollection<BsonDocument> _acountDoc = GetCollections(EDBINFOS.EDBINFO_KEYINDEX.GetDescription());
                _keyindexCollection.Clear();
                _keyindexCollection.Add(EDBINFOS.EDBINFO_KEYINDEX, _acountDoc);
                _keyindexCollection.Add(EDBINFOS.EDBINFO_ACOUNT, GetCollections(EDBINFOS.EDBINFO_ACOUNT.GetDescription()));
                _keyindexCollection.Add(EDBINFOS.EDBINFO_QUESTION, GetCollections(EDBINFOS.EDBINFO_QUESTION.GetDescription()));
                _keyindexCollection.Add(EDBINFOS.EDBINFO_QUESLOG, GetCollections(EDBINFOS.EDBINFO_QUESLOG.GetDescription()));

                _autoIndexMgr = new AutoIndexManager(ref _acountDoc);
            }
            catch (MongoDB.Driver.MongoAuthenticationException ex)
            {
                MessageBox.Show(ex.ToString());
            }
            
        }
        private MongoCollection<BsonDocument> GetCollections(string collectionName)
        {
            if (mongoDatabase == null) return null;
            return mongoDatabase.GetCollection<BsonDocument>(collectionName);
        }
        public MongoCollection<BsonDocument> GetCollections(EDBINFOS ecollection)
        {
            if (mongoDatabase == null) return null;
            if (_keyindexCollection.ContainsKey(ecollection))
                return _keyindexCollection[ecollection];
            return null;
        }
        public bool GoAuthUser(string _username,string _password,bool bAdmin)
        {
            try
            {
                MongoCollection<BsonDocument> _acounts = GetCollections(EDBINFOS.EDBINFO_ACOUNT);
                long ic = _acounts.Count();
                m_bSuccessLogin = true;
                m_strLoginUserName = _username;
                if (ic > 0)
                {
                    IMongoQuery query = Query.And(Query.EQ("USERNAME", _username));//同时满足多个条件
                    MongoCursor<BsonDocument> cursor = _acounts.Find(query);
                    long ifinds = cursor.Count();
                    if (ifinds == 1)
                    {

                        BsonDocument bd = cursor.ToBsonDocument();
                        m_strLoginUserName = bd["NAME"].ToString();

                    }
                }
            }
            catch (MongoDB.Driver.MongoConnectionException ex)
            {
                m_bSuccessLogin = false;
                m_strLoginUserName = "";
                return false;
            }
            return true;
        }
        public void QuitSystem()
        {
            if (gmongoServer != null)
                gmongoServer.Disconnect();
            m_bSuccessLogin = false;
            m_strLoginUserName = "";
            
        }
        public bool InsertQuestionItem(ref MDTB_QUESTION _question)
        {
            if (!m_bSuccessLogin)
                return false;
            MongoCollection<BsonDocument> _questionDoc = GetCollections(EDBINFOS.EDBINFO_QUESTION);
            _question.INDEXID = _autoIndexMgr.GetNewIndex(EDBINFOS.EDBINFO_QUESTION);
            BsonDocument bd = BsonExtensionMethods.ToBsonDocument(_question);
            WriteConcernResult rsl = _questionDoc.Insert(bd);
            MongoDB.Bson.ObjectId _id = bd["_id"].AsObjectId;
            bool iserr = rsl.HasLastErrorMessage;
            return iserr;
        }
    }
}
